<html>
<head>
<title>CpcPaChi - Version 0.05</title>
<style type="text/css">
span {
  font-family: 'Courier New';
  font-size: 10pt;
  color: #000000;
}
.sc0 {
  color: #808080;
}
.sc3 {
  color: #008080;
}
.sc4 {
  color: #FF8000;
}
.sc5 {
  font-weight: bold;
  color: #0000FF;
}
.sc7 {
  color: #808080;
}
.sc9 {
  color: #804000;
}
.sc10 {
  font-weight: bold;
  color: #000080;
}
.sc11 {
}
</style>
</head>
<body>
<h2>Un compilador sencillo paso a paso (5)</h2>

<p align="right">(Volver al <a href="doc.html">&iacute;ndice</a>) </p>

<p>En el quinto acercamiento vamos a reconocer una estructura algo m&aacute;s parecida
a un fuente "real" en pascal, que comience con "program" y tenga un cuerpo
de programa delimitado ente "begin" y "end", incluso con espacios en blanco,
como &eacute;sta:</p>

<pre><code>
program ej;
begin
 &nbsp;cls;
 &nbsp;locate(10,5);
 &nbsp;writeChar( 'a' );
 &nbsp;locate ( 1 ,  10 );
 &nbsp;writeChar('c');
end.
</code></pre>

<p>Esto supone dos cambios:</p>

<ul>
  <li>Vamos a sacar del cuerpo del programa lo que ser&aacute; el "analizador
    sint&aacute;ctico", el encargado de indicar en qu&eacute; orden deben estar los
    elementos del programa (por ejemplo: despu&eacute;s de "program" debe aparecer
    un identificador y un punto y coma, luego "begin" y una secuencia
    de &oacute;rdenes, etc).</li>
  <li>Ampliaremos un poco el analizador l&eacute;xico para que sea capaz
    de "saltarse" los espacios en blanco.</li>
</ul>

<p>En cuanto al "analizador sint&aacute;ctico", simplemente ampliamos el anterior
"analizarCualquierOrden", que ahora estar&aacute; dentro de un "analizarPrograma",
que se asegura de que antes aparezca program, begin, etc, as&iacute;:</p>

<pre><code>
public void AnalizarPrograma()
{
  /* program &lt;identificador&gt;; */
  string orden = miLexer.ObtenerIdentificador().ToUpper();
  if ( orden != &quot;PROGRAM&quot; )
  {
    Console.WriteLine(&quot;No se ha encontrado PROGRAM&quot;);
    Environment.Exit(1);
  }
  orden = miLexer.ObtenerIdentificador(); // Nombre de programa
  miLexer.LeerSimbolo(';');

  /* begin */
  orden = miLexer.ObtenerIdentificador().ToUpper();
  if ( orden != &quot;BEGIN&quot; )
  {
    Console.WriteLine(&quot;No se ha encontrado BEGIN&quot;);
    Environment.Exit(1);
  }

  /* Resto de ordenes */
  do
    analizarCualquierOrden();
  while ( ! analisisTerminado );
}
</code></pre>

<p><br>Por lo que respecta al analizador l&eacute;xico, cada vez que vayamos a leer
un identificador, un entero o a esperar un s&iacute;mbolo concreto, deberemos
antes saltar los espacios en blanco que pudiera haber:</p>


<pre><code>
public int ObtenerEntero()
{
  saltarBlancos();
  string lexema = &quot;&quot;;
  char letra = ObtenerLetra();
  [...]

void saltarBlancos()
{
  // Leo el siguiente s&iacute;mbolo y repito mientras sea un blanco
  char proximaLetra = ObtenerLetra();

  while ((proximaLetra == ' ') || (proximaLetra == '\n') ||
        (proximaLetra == '\r') ||  (proximaLetra == '\t') )
    proximaLetra = ObtenerLetra();

  // Finalmente he leido uno de mas, asi que retrocedo
  if (posicionLineaActual &gt; 0)
    posicionLineaActual --;

}
</code></pre>

<p><br>Para m&aacute;s detalles, todo el c&oacute;digo est&aacute; en la p&aacute;gina del proyecto en Google Code:<br /><br /><a href="http://code.google.com/p/cpcpachi/">http://code.google.com/p/cpcpachi/</a></p>



<p align="right">(Volver al <a href="doc.html">&iacute;ndice</a>) </p>
</body>
</html>
